<?php
/**
 * @package mikrokosmos
 * mk image library file created on  7-nov-2004
 * jaco_at_pixeldump_dot_org
 */


/**
 * private:
 * reads bitmap data
 * image types:
 * JPEG 			-> DefineBits
 * JPEG2			-> DefineBitsJPEG2
 * JPEG_ALPHA		-> DefineBitsJPEG3
 * IMAGE_LOSSLESS	-> DefineBitsLossless
 * IMG_LS_PALETTE_8 -> 3
 * IMG_LS_PALETTE_15 -> 4
 * IMG_LS_RGB	-> 5
 * IMAGE_LOSSLESS_ALPHA -> DefineBitsLossless2
 * IMG_LS_PALETTE_8_ALPHA	-> 3
 * IMG_LS_RGB_ALPHA -> 5
 */
function read_bitmapTag($bmTagType, $bmTagData){
	//echo "<br />reading bitmap";

	$bitmap = array();
	$bitmap["id"] = ui16dec(substr($bmTagData, 0, 2));
	$bitmap["bitmapType"] = $bmTagType;
	$bitmap["bitDepth"] = 0;
	$bitmap["rawData"] = $bmTagData;
	$bitmap["jpegTable"] = "";
	$bitmap["jpegData"] = "";
	$bitmap["rgbData"] = "";
	$bitmap["alphaData"] = "";
	$bitmap["pixelData"] = "";
	$bitmap["colorTable"] = "";

	if($bitmap["bitmapType"] == JPEG_TABLE){ // jpegTable
		$bitmap["jpegTable"] = $bmTagData;
	}
	else if($bitmap["bitmapType"] == JPEG){
		$bitmap["jpegData"] = translate_jpeg(substr($bmTagData, 2));
	}
	else if($bitmap["bitmapType"] == JPEG2){
		$bitmap["jpegData"] = translate_jpeg(substr($bmTagData, 2));
	}
	else if($bitmap["bitmapType"] == JPEG_ALPHA){

		$jpegSize = ui32dec(substr($bmTagData, 2, 4));
		$bitmap["jpegData"] = translate_jpeg(substr($bmTagData, 6, $jpegSize));
		$bitmap["alphaData"] = gzuncompress(substr($bmTagData, 6 + $jpegSize));
	}

	if(strlen($bitmap["jpegData"])){

		$jpegwh = get_jpeg_dimensions(substr($bitmap["jpegData"], 0 ,1024));

	 	$bitmap["bitmapWidth"] = $jpegwh["jpegWidth"];
		$bitmap["bitmapHeight"] = $jpegwh["jpegHeight"];
		return $bitmap;
	}

	$bitmap["bitDepth"] = ui8dec($bmTagData[2]);
	$bitmap["bitmapWidth"] = ui16dec(substr($bmTagData, 3, 2));
	$bitmap["bitmapHeight"] = ui16dec(substr($bmTagData, 5, 2));

	if($bitmap["bitmapType"] == IMAGE_LOSSLESS){

		if($bitmap["bitDepth"] == IMG_LS_PALETTE_8){

			$colormapData = gzuncompress(substr($bmTagData, 8));
			$ctSize = ui8dec($bmTagData[7]) + 1;
			$ctOffset = $ctSize * 3;

			$bitmap["colorTable"] = substr($colormapData, 0, $ctOffset);
			$bitmap["pixelData"] = substr($colormapData, $ctOffset);
		}
		else if($bitmap["bitDepth"] == IMG_LS_PALETTE_15){
			$rawPixeldata = gzuncompress(substr($bmTagData, 7));
			$bitmap["rgbData"] = get_rgbData($rawPixeldata, IMG_LS_PALETTE_15);
			unset($rawPixeldata);
		}
		else if($bitmap["bitDepth"] == IMG_LS_RGB){

			$rawPixeldata = gzuncompress(substr($bmTagData, 7));
			$bitmap["rgbData"] = get_rgbData($rawPixeldata, IMG_LS_RGB);
			unset($rawPixeldata);
		}
	}
	else if($bitmap["bitmapType"] == IMAGE_LOSSLESS_ALPHA){

		if($bitmap["bitDepth"] == IMG_LS_PALETTE_8_ALPHA){

			$alphacolorData = gzuncompress(substr($bmTagData, 8));
			$ctSize = ui8dec($bmTagData[7]) + 1;
			$ctOffset = $ctSize * 4;

			$rgbacolorTable = substr($alphacolorData, 0, $ctOffset);
			$bitmap["colorTable"] = get_LS8_colorTable($rgbacolorTable);
			$bitmap["alphaData"] = get_LS8_alphaData($rgbacolorTable);
			$bitmap["pixelData"] = substr($alphacolorData, $ctOffset);

			unset($alphacolorData);
		}
		else if($bitmap["bitDepth"] == IMG_LS_RGB_ALPHA){

			$rawPixeldata = gzuncompress(substr($bmTagData, 7));
			$bitmap["rgbData"] = get_rgbData($rawPixeldata, IMG_LS_RGB_ALPHA, $bitmap["bitmapWidth"], $bitmap["bitmapHeight"]);
			$bitmap["alphaData"] = get_alphaData($rawPixeldata);
			unset($rawPixeldata);
		}

	}

	return $bitmap;
}

/**
 * private:
 * get jpeg data and "translate" to a valid jpeg image
*/
function translate_jpeg($rawJPEG){

		$EOI = chr(0xff) .chr(0xd9);
		$es = strpos($rawJPEG, $EOI);

		if($es != strlen($rawJPEG)){ // jpegTableMisc + jpegImage

			$jpegTable = substr($rawJPEG, 0, $es);
			$jpegImage = substr($rawJPEG, $es + 4);
			$jpegData = $jpegTable .$jpegImage;

			return $jpegData;
		}
		else return $rawJPEG;		// regular jpegData
}


 /**
  * generic:
  * return an array containing width and height of a jpeg image
  * only a part of jpeg data is necessary
  */
 function get_jpeg_dimensions($jpegChunk){

 	$jpegDim = array();
 	$dMark = chr(0xff) .chr(0xc0);
 	$marker = strpos($jpegChunk, $dMark);
 	$jpegDim["jpegType"] = JPEG_BASELINE;


 	if($marker === false) {
 		$dMark = chr(0xff) .chr(0xc2); // progressive jpeg
 		$marker = strpos($jpegChunk, $dMark);
 		$jpegDim["jpegType"] = JPEG_PROGRESSIVE;
 	}

 	$jpegDim["jpegHeight"] = hexdec(bin2hex(substr($jpegChunk, $marker + 5, 2)));
 	$jpegDim["jpegWidth"] = hexdec(bin2hex(substr($jpegChunk, $marker + 7, 2)));

 	return $jpegDim;
 }


/**
 * generic:
 * reads some jpeg data from jpeg file
 * wrapper for get_jpeg_dimension
 */
function get_jpeg_dimensions_from_file($jpgPath){

	$fi = fopen($jpgPath, "rb");
	$jpgChunk = fread($fi, 1024);
	fclose($fi);

	return get_jpeg_dimensions($jpgChunk);
}


 /**
  * generic:
  * reads IHDR png data, determining:
  * image width
  * image height
  * bit depth
  * color type
  * compression type
  * filter method
  * interlace method
  */
function get_IHDR_data($pngChunk){

	//Width: 4 bytes
	//Height: 4 bytes
	//Bit depth: 1 byte
	//Color type: 1 byte
	//Compression method: 1 byte
	//Filter method: 1 byte
	//Interlace method: 1 byte

	$ihdrStr = "IHDR";
	$ihdrData = array();

	$iho = strpos($pngChunk, $ihdrStr) + strlen($ihdrStr);

	$ihdrData["pngWidth"] = hexdec(bin2hex(substr($pngChunk, $iho, 4)));
	$ihdrData["pngHeight"] = hexdec(bin2hex(substr($pngChunk, $iho + 4, 4)));
	$ihdrData["bitDepth"] = hexdec(bin2hex($pngChunk[$iho + 8]));
	$ihdrData["colorType"] = hexdec(bin2hex($pngChunk[$iho + 9]));
	$ihdrData["cmpMethod"] = hexdec(bin2hex($pngChunk[$iho + 10]));
	$ihdrData["filterMethod"] = hexdec(bin2hex($pngChunk[$iho + 11]));
	$ihdrData["itlMethod"] = hexdec(bin2hex($pngChunk[$iho + 12]));

	return $ihdrData;
}

/**
 * generic:
 * reads IHDR png data from a png image file
 * wrapper for get_IHDR_data
 */
function get_IHDR_data_from_file($pngPath){

	$fi = fopen($pngPath, "rb");
	$pngChunk = fread($fi, 1024);
	fclose($fi);

	return get_IHDR_data($pngChunk);
}


 /**
  * private: converts 15 bit pixelmap to rgb
  */
 function get_rgbData($rawColordata, $rawType, $bimapWidth = 0, $bitmapHeight = 0){ // note that rgbData does not contains reserved values as in swf

 	$rgbData = "";
 	$rcdSize = strlen($rawColordata);

 	if($rawType == IMG_LS_PALETTE_15){

 		for($i = 0; $i < $rcdSize; $i += 2){

 			$pix15 = substr($rawColordata, $i, 2);

 			$strBin = swf_value2bin($pix15, 16);

 			$strRed = substr($strBin, 1, 5);
 			$strGreen = substr($strBin, 6, 5);
 			$strBlue = substr($strBin, 11, 5);

 			$rgbData .= chr(bindec($strRed));
 			$rgbData .= chr(bindec($strGreen));
 			$rgbData .= chr(bindec($strBlue));
 		}
 	}
 	else if($rawType == IMG_LS_RGB || $rawType == IMG_LS_RGB_ALPHA){ // loose reserved byte (0, r, g, b)

		for($i = 0; $i < $rcdSize; $i += 4){

			$pix32 = substr($rawColordata, $i, 4);

			$rgbData .= $pix32[1];
			$rgbData .= $pix32[2];
			$rgbData .= $pix32[3];
 		}
 	}

 	return $rgbData;
 }



/**
 * return alpha pixelmap
 */
function get_alphaData($rawColordata){

	$alphaData = "";
	$rcdSize = strlen($rawColordata);

	for($i = 0; $i < $rcdSize; $i += 4){
		$rgba = substr($rawColordata, $i , 4);
		$alphaData .= $rgba[0];
	}

	return $alphaData;
}


/**
 * private:
 * get alpha channel data
 */
 function get_LS8_alphaData($rgbacolorTable){

 	$alphaData = "";
 	$rctSize = strlen($rgbacolorTable);

 	for($k = 0; $k < $rctSize; $k += 4) { $alphaData .= $rgbacolorTable[$k + 3]; }

 	return $alphaData;
 }

/**
 * private:
 * get color Table data
 */
 function get_LS8_colorTable($rgbacolorTable){

 	$colorTable = "";
 	$rctSize = strlen($rgbacolorTable);

 	for($k = 0; $k < $rctSize; $k += 4) {

 		$colorTable .= $rgbacolorTable[$k + 0];
 		$colorTable .= $rgbacolorTable[$k + 1];
 		$colorTable .= $rgbacolorTable[$k + 2];
 	}

 	return $colorTable;
 }

/**
 * generic:
 * return a convenient human-readable definition for image type
 */
 function get_imageType($bmType){

 	$strTypes = array();
 	$strTypes[JPEG_TABLE] = "jpegTables";
 	$strTypes[JPEG] = "lossy";
 	$strTypes[JPEG2] = "lossy";
 	$strTypes[JPEG_ALPHA] = "lossy";
 	$strTypes[IMAGE_LOSSLESS] = "full data";
 	$strTypes[IMAGE_LOSSLESS_ALPHA] = "full data";

	return $strTypes[$bmType];
 }

/**
 * generic:
 * return a convenient human-readable definition for image bit depth
 */
 function get_image_bitDepth($bmDepth){

 	//echo "<br />i have bmDepth: " . $bmDepth;
 	$strDepths = array();
 	$strDepths[0] = "24";
 	$strDepths[JPEG_TABLE] = "0";
 	$strDepths[IMG_LS_PALETTE_8] = "8";
 	$strDepths[IMG_LS_PALETTE_15] = "15";
 	$strDepths[IMG_LS_RGB] = "24";
 	$strDepths[IMG_LS_PALETTE_8_ALPHA] = "8";
 	$strDepths[IMG_LS_RGB_ALPHA] = "24";

 	return $strDepths[$bmDepth];
 }


/**
 * generic: retrieve a valid image file name based on
 * swf file name, frame index (starting from 1), character id
 * bitmap type, if not given returns base file name
 */
function get_imageFileName($swfFileName, $frameIndex = 0, $bitmapID = 0, $bitmapType = ""){

	$ifn = substr($swfFileName, 0, strlen($swfFileName) - 4);
	if($frameIndex){
		$ifn .= "_";
		$ifn .= get_fixedHex($frameIndex, 4);
	}
	if($bitmapID){
		$ifn .= "_";
		$ifn .= get_fixedHex($bitmapID, 4);
	}
	if(strlen($bitmapType)) {
		$ext = get_image_ext($bitmapType);
		$ifn = $ifn ."." .$ext;
	}

	return $ifn;
}


/**
 * generic: retrieve a valid extension image file name
 * based on image type
 */
function get_image_ext($bitmapType){

 	$extTypes = array();

 	$extTypes[JPEG_TABLE] = "jt";
 	$extTypes[JPEG] = "jpg";
 	$extTypes[JPEG2] = "jpg";
 	$extTypes[JPEG_ALPHA] = "png";
 	$extTypes[IMAGE_LOSSLESS] = "png";
 	$extTypes[IMAGE_LOSSLESS_ALPHA] = "png";

	return $extTypes[$bitmapType];
}


/**
 * generic: returns extension from given file name
 */
//function get_file_ext($fileName){ return substr($fileName, -3); }
function get_file_ext ($fileName) {
	$fileName = strtolower($fileName) ;
	$extAr = split("[/\\.]", $fileName) ;
	return $extAr[count($extAr) - 1];
}


/**
 *
 */
function read_image_as_alpha($imgAlphaPath) {
	$imgSize = getimagesize(($imgAlphaPath));
	$img = imagecreatefrompng($imgAlphaPath);
	$alphaData = "";

	for($y = 0; $y < $imgSize[1]; $y++){

		for($x = 0; $x < $imgSize[0]; $x++){
			$alphaData .= chr(imagecolorat($img, $x, $y));
		}
	}

	return $alphaData;
}

/**
 * private:
 * save a full data image
 */
function save_lossless_rgb($pngout, $rgbData, $bitmapWidth, $bitmapHeight){

  $img = imagecreatetruecolor($bitmapWidth, $bitmapHeight);

  for($y = 0, $k = 0; $y < $bitmapHeight; $y++){

	for($x = 0; $x < $bitmapWidth; $x++, $k += 3){

	  $col = imagecolorallocate($img,
	  							ui8dec($rgbData[$k]),
	  							ui8dec($rgbData[$k + 1]),
	  							ui8dec($rgbData[$k + 2]));

	  imagesetpixel($img, $x, $y, $col);
	}
  }

  imagepng($img, $pngout);
  imagedestroy($img);
}


/**
 * private:
 * save a full data image with alpha channel
 */
function save_lossless_rgb_alpha($pngout, $rgbData, $alphaData, $bitmapWidth, $bitmapHeight){

  $img = imagecreatetruecolor($bitmapWidth, $bitmapHeight);

  imagealphablending($img, false);
  imagesavealpha($img, true);
  $a = 0;

  for($y = 0, $k = 0; $y < $bitmapHeight; $y++){

	for($x = 0; $x < $bitmapWidth; $x++, $k += 3){

	  $pixAlpha = 127 - floor(ui8dec($alphaData[$a++]) / 2);

	  $col = imagecolorallocatealpha($img,
	  							ui8dec($rgbData[$k]),
	  							ui8dec($rgbData[$k + 1]),
	  							ui8dec($rgbData[$k + 2]),
	  							$pixAlpha);

	  imagesetpixel($img, $x, $y, $col);
	}
  }

  imagepng($img, $pngout);
  imagedestroy($img);
}


/**
 * private:
 * save a lossy data image with alpha channel to png file
 */
function save_jpeg_alpha($pngout, $jpegData, $alphaData, $bitmapWidth, $bitmapHeight){

  $jpgFileName = substr($pngout, 0, -4) ."__.jpg";

  $jpgout = fopen($jpgFileName, "wb");
  fwrite($jpgout, $jpegData, strlen($jpegData));
  fclose($jpgout);

  $img = imagecreatetruecolor($bitmapWidth, $bitmapHeight);
  $jpg = imagecreatefromjpeg($jpgFileName);

  imagealphablending($img, false);
  imagesavealpha($img, true);
  $a = 0;

  for($y = 0, $k = 0; $y < $bitmapHeight; $y++){

	for($x = 0; $x < $bitmapWidth; $x++){

	  $pixAlpha = 127 - floor(ui8dec($alphaData[$a++]) / 2);

	  $rgb = imagecolorat($jpg, $x, $y);
	  $srcCol = imagecolorsforindex($jpg, $rgb);

	  $diff = $pixAlpha *  2;
	  $red = min(($srcCol["red"] + $diff), 0xFF);
	  $green = min(($srcCol["green"] + $diff), 0xFF);
	  $blue = min(($srcCol["blue"] + $diff), 0xFF);

	  $col = imagecolorallocatealpha($img, $red, $green, $blue, $pixAlpha);
	  imagesetpixel($img, $x, $y, $col);
	}
  }

  imagepng($img, $pngout);
  imagedestroy($img);
  imagedestroy($jpg);
}


/**
 * private:
 * save a lossless data image
 */
function save_lossless_8 ($pngout, $pixelData, $colorTable, $bitmapWidth, $bitmapHeight){

  $img = imagecreatetruecolor($bitmapWidth, $bitmapHeight);
  $ctSize = strlen($colorTable) / 3;
  $colors = array();
  $pad = 4 - $bitmapWidth % 4;

  if($pad == 4) $pad = 0;
  $wPad = $bitmapWidth + $pad;

  for($i = 0, $k = 0; $i < $ctSize; $i++, $k += 3){
  	$colors[$i]["red"] = ui8dec($colorTable[$k]);
  	$colors[$i]["green"] = ui8dec($colorTable[$k + 1]);
  	$colors[$i]["blue"] = ui8dec($colorTable[$k + 2]);
  }

  for($y = 0; $y < $bitmapHeight; $y++){

  	$baseIndex = $wPad * $y;

	for($x = 0; $x < $bitmapWidth; $x++){

	  $pixIdx = ui8dec($pixelData[$baseIndex++]);

	  $col = imagecolorallocate($img,
	  							$colors[$pixIdx]["red"],
	  							$colors[$pixIdx]["green"],
	  							$colors[$pixIdx]["blue"]);

	  imagesetpixel($img, $x, $y, $col);
	}
  }

  imagepng($img, $pngout);
  imagedestroy($img);
}



/**
 * private:
 * save a lossless data image with alpha channel
 */
function save_lossless_8_alpha ($pngout, $pixelData, $colorTable, $alphaData, $bitmapWidth, $bitmapHeight){

  $img = imagecreatetruecolor($bitmapWidth, $bitmapHeight);
  imagealphablending($img, false);
  imagesavealpha($img, true);

  $ctSize = strlen($colorTable) / 3;
  $colors = array();
  $pad = 4 - $bitmapWidth % 4;

  if($pad == 4) $pad = 0;
  $wPad = $bitmapWidth + $pad;

  for($i = 0, $k = 0; $i < $ctSize; $i++, $k += 3){

  	$colors[$i]["red"] = ui8dec($colorTable[$k]);
  	$colors[$i]["green"] = ui8dec($colorTable[$k + 1]);
  	$colors[$i]["blue"] = ui8dec($colorTable[$k + 2]);
  	$colors[$i]["alpha"] = 127 - floor(ui8dec($alphaData[$i]) / 2);
  }

  for($y = 0; $y < $bitmapHeight; $y++){

  	$baseIndex = $wPad * $y;

	for($x = 0; $x < $bitmapWidth; $x++){


	  $pixIdx = ui8dec($pixelData[$baseIndex++]);

	  $col = imagecolorallocatealpha($img,
	  							$colors[$pixIdx]["red"],
	  							$colors[$pixIdx]["green"],
	  							$colors[$pixIdx]["blue"],
	  							$colors[$pixIdx]["alpha"]);

	  imagesetpixel($img, $x, $y, $col);
	}
  }

  imagepng($img, $pngout);
  imagedestroy($img);
}

/**
 * private: save 8bpp png with alpha data
 */
function save_gray_alpha($pngout, $alphaData, $bitmapWidth, $bitmapHeight) {

  $img = imagecreatetruecolor($bitmapWidth, $bitmapHeight);
  $a = 0;

  for($y = 0; $y < $bitmapHeight; $y++){

  	for($x = 0; $x < $bitmapWidth; $x++){

  		$rc = ui8dec($alphaData[$a++]);

  		$col = imagecolorallocate($img, $rc, $rc, $rc);
  		imagesetpixel($img, $x, $y, $col);
  	}
  }

  imagepng($img, $pngout);
  imagedestroy($img);
}


/**
 * private: save 8bpp png havint 2bit alpha data
 */
function save_index_alpha($pngout, $alphaData, $pixelData, $bitmapWidth, $bitmapHeight){

  $img = imagecreatetruecolor($bitmapWidth, $bitmapHeight);

  $pad = 4 - $bitmapWidth % 4;

  if($pad == 4) $pad = 0;
  $wPad = $bitmapWidth + $pad;

  for($y = 0; $y < $bitmapHeight; $y++){

  	$baseIndex = $wPad * $y;

	for($x = 0; $x < $bitmapWidth; $x++){

	  $pixIdx = ui8dec($pixelData[$baseIndex++]);
	  $rc = ui8dec($alphaData[$pixIdx]);

  	  $col = imagecolorallocate($img, $rc, $rc, $rc);
  	  imagesetpixel($img, $x, $y, $col);
	}
  }

  imagepng($img, $pngout);
  imagedestroy($img);
}


/**
 * private:
 * writes swf bitmap tag type
 * from given JPEG image
 */
function write_bitmapTag_jpeg($bitmapType,
							$bitmapID,
							$imagePath,
							$alphaData = "",
							$quality = 100,
							$wrapArray = false){

	global $swfTagList;

	$bitDepth = 0;
	$rawData = "";
	$jpegData = "";
	$rgbData = "";
	$pixelData = "";
	$colorTable = "";
	$tmpPath = "";

	$bs = getimagesize($imagePath);
	$ext = get_file_ext($imagePath);

	if($ext == "jpg"){
		$jpgin = fopen($imagePath, "rb");
		$jpegChunk = fread($jpgin, 1024);
		fclose($jpgin);

		$jd = get_jpeg_dimensions($jpegChunk);

		//if($jd["jpegType"] == JPEG_BASELINE) {
		//	$tmpPath = $imagePath;
		//}

		$img = imagecreatefromjpeg($imagePath);
	}
	else if($ext == "png") $img = imagecreatefrompng($imagePath);
	else if($ext == "gif") $img = imagecreatefromgif($imagePath);

	if(!$img) return "";
	if(!strlen($tmpPath)) $tmpPath = SERVER_MKTMP ."ls" .$ext ."_" .mktime() .".jpg";

	$rawData = swf_word($bitmapID);

	if(strlen($alphaData)){
		$bitmapType = JPEG_ALPHA;
		$step = 1 / 0xFF;
		$z = 0;

		for($y = 0; $y < $bs[1]; $y++){
			for($x = 0; $x < $bs[0]; $x++){

				$alphaMul = ui8dec($alphaData[$z++]) * $step;
				$rgb = imagecolorat($img, $x, $y);
				$srcCol = imagecolorsforindex($img, $rgb);

				$srcCol["red"] = floor($alphaMul * $srcCol["red"]);
				$srcCol["green"] = floor($alphaMul * $srcCol["green"]);
				$srcCol["blue"] = floor($alphaMul * $srcCol["blue"]);

				$col = imagecolorallocate($img, $srcCol["red"], $srcCol["green"], $srcCol["blue"]);
				imagesetpixel($img, $x, $y, $col);
			}
		}
	}

	imagejpeg($img, $tmpPath, $quality);
	imagedestroy($img);

	$jpgSize = filesize($tmpPath);

	$fin = fopen($tmpPath, "rb");
	$jpgData = fread($fin, $jpgSize);
	fclose($fin);


	if(strlen($alphaData)) {
		$rawData .= swf_dword($jpgSize);
		$rawData .= $jpgData;
		$rawData .= gzcompress($alphaData, 9);
	}
	else {
		$rawData .= $jpgData;
	}

	$rs = strlen($rawData);
	$bitmapTag = SWFTag_long_header($swfTagList[$bitmapType], $rs);
	$bitmapTag .= $rawData;

	if($wrapArray){

		$bmAr = array();
		$bmAr["binData"] = $bitmapTag;
		$bmAr["bitmapWidth"] = $bs[0];
		$bmAr["bitmapHeight"] = $bs[1];

		return $bmAr;
	}

	return $bitmapTag;
}

/**
 * private:
 * writes swf bitmap tag type
 * from given PNG image
 */
function write_bitmapTag_png($bitmapID, $imagePath, $wrapArray = false){

	global $swfTagList;

	$bitDepth = 0;
	$rawData = "";
	$jpegData = "";
	$rgbData = "";
	$alphaData = "";
	$pixelData = "";
	$colorTable = "";

	$ihdr = get_IHDR_data_from_file($imagePath);

	$img = imagecreatefrompng($imagePath);

	$rawData = "";
	$bitmapTag = "";

	if($ihdr["colorType"] == PNG_RGB_ALPHA){

		$bitmapType = IMAGE_LOSSLESS_ALPHA;

		$alphaStep = 255 / 127;
		$alhpaLookup = array();
		$alBin = array();

		// create lookup table for alpha values
		// since gd returns 127 - 0 instead of 0 - 255
		for($i = 0; $i < 128; $i++){
			$v = 255 - round($i * $alphaStep);
			$alphaLookup[$i] = $v;
			$alBin[$i] = chr($v);
		}

  		for($y = 0; $y < $ihdr["pngHeight"]; $y++){
			for($x = 0; $x < $ihdr["pngWidth"]; $x++){

				$ci = imagecolorat($img, $x,  $y);
				$rgba = imagecolorsforindex($img, $ci);


				// for a reason that I don't know
				// colors are rendered quirkly if their values are upper than alpha
				// so we have to accommodate colors depending on alpha value
				$iAlpha	= $alphaLookup[$rgba["alpha"]];
				$maxC = $iAlpha - 2;

				if($iAlpha <= 2){
					$rgba["red"] = $rgba["green"] = $rgba["blue"] = 0;
				}
				else if($maxC < 253){

					$r = 0xFF / $maxC;
					$rgba["red"] = floor($rgba["red"] / $r);
					$rgba["green"] = floor($rgba["green"] / $r);
					$rgba["blue"] = floor($rgba["blue"] / $r);
				}

				$rawData .= $alBin[$rgba["alpha"]];
				$rawData .= chr($rgba["red"]);
				$rawData .= chr($rgba["green"]);
				$rawData .= chr($rgba["blue"]);
			}
		}

		$cmpData = gzcompress($rawData, 9);
		$bodySize = strlen($cmpData) + 7;

		$bitmapTag = SWFTag_long_header($swfTagList[$bitmapType], $bodySize);
		$bitmapTag .= swf_word($bitmapID);
		$bitmapTag .= chr(IMG_LS_RGB_ALPHA);				// 24 bpp image type
		$bitmapTag .= swf_word($ihdr["pngWidth"]);
		$bitmapTag .= swf_word($ihdr["pngHeight"]);
		$bitmapTag .= $cmpData;
	}
	else if($ihdr["colorType"] == PNG_RGB){

		$bitmapType = IMAGE_LOSSLESS;

		for($y = 0; $y < $ihdr["pngHeight"]; $y++){
			for($x = 0; $x < $ihdr["pngWidth"]; $x++){

				$ci = imagecolorat($img, $x,  $y);
				$rgba = imagecolorsforindex($img, $ci);

				$rawData .= NIL;
				$rawData .= chr($rgba["red"]);
				$rawData .= chr($rgba["green"]);
				$rawData .= chr($rgba["blue"]);
			}
		}

		$cmpData = gzcompress($rawData, 9);
		$bodySize = strlen($cmpData) + 7;

		$bitmapTag = SWFTag_long_header($swfTagList[$bitmapType], $bodySize);
		$bitmapTag .= swf_word($bitmapID);
		$bitmapTag .= chr(IMG_LS_RGB);				// 24 bpp image type
		$bitmapTag .= swf_word($ihdr["pngWidth"]);
		$bitmapTag .= swf_word($ihdr["pngHeight"]);
		$bitmapTag .= $cmpData;
	}

	imagedestroy($img);

	if($wrapArray){

		$bmAr = array();
		$bmAr["binData"] = $bitmapTag;
		$bmAr["bitmapWidth"] = $ihdr["pngWidth"];
		$bmAr["bitmapHeight"] = $ihdr["pngHeight"];

		return $bmAr;
	}

	return $bitmapTag;
}

/**
 * private:
 * create a shape character that will represent bitmap in the movie
 */
function create_bitmap_shapeTag($shapeID, $bitmapID, $bitmapWidth, $bitmapHeight, $x = 0, $y = 0){

	global $swfTagList;
	// in this section we build defineshape tag
	$bmShapeTag = swf_word($shapeID);

	$bmShapeTag .= swf_rect($x, $y, $bitmapWidth, $bitmapHeight); // rect structure for defineshape

	//SHAPEWITHSTYLE
	$bmShapeTag .= chr(0x01); // 1 fillstylecount
	$bmShapeTag .= chr(0x41); // clipped bitmap fill

	$bmShapeTag .= swf_word($bitmapID);

	//	MATRIX
	$bmShapeTag .= chr(0xd9);
	$bmShapeTag .= chr(0x40);
	$bmShapeTag .= chr(0x00);
	$bmShapeTag .= chr(0x05);
	$bmShapeTag .= chr(0x00);
	$bmShapeTag .= chr(0x00);
	$bmShapeTag .= chr(0x00);

	$bmShapeTag .= chr(0x00); // no linestyle array
	$bmShapeTag .= chr(0x10); //

	$bmShapeTag .= swf_shape_record_rect($x, $y, $bitmapWidth, $bitmapHeight);

	$strdsSize = strlen($bmShapeTag);

	$bmShapeHead = SWFTag_long_header($swfTagList["DefineShape"], $strdsSize);

	return $bmShapeHead .$bmShapeTag;
}



/**
 *   +-------------------------------------------------+
 *   |  J P G   T h u m b n a i l   G e n e r a t o r  |
 *   +--------------------+----------------------------+
 *   |  by Kadir Yazgan   |  ( kadiryazgan@ixir.com )  |
 *   +--------------------+----------------------------+
 *      v1.0
 *
 *   Generates a proportional thumbnail image with a given width.
 *
 *   This script only uses JPEG files. If required libraries are included GIF and PNG files can
 *   also be supported the same way.
 *
 *   P a r a m e t e r s
 *       $jpegDir:     Directory where original images reside.
 *       $tnDir:       Directory where the thumbnails will be saved.
 *       $tn_w:        Thumbnail width.
 * 		 $jpegQuality: quality of compression (0 - 100)
 *
 *  note: heavingly edited by jaco_at_pixeldump
 *
 */
function thumbnailize_jpeg($jpegFN, $jpegDir, $tnDir, $tn_w = 100, $jpegQuality = 100){

	// Define the original image
    if (!isset($jpegFN)) return 1;

	// Check if the file exists
    if (!file_exists($jpegDir .$jpegFN)) return 2;

	// Check if the file extesion is .jpg
    $ext = explode('.', $jpegFN);
    $ext = $ext[count($ext)-1];
    if (strtolower($ext) != "jpg") return 3;

	// Read the source image
    $src_img = ImageCreateFromJPEG($jpegDir .$jpegFN);

	// Get image width and height
    $org_h = imagesy($src_img);
    $org_w = imagesx($src_img);

	// Calculate thumbnail height
    $tn_h = floor($tn_w * $org_h / $org_w);
	//$tn_h = $tn_w; // forced square thumb

	// Initialize temp image
    $tmp_img = imagecreatetruecolor($tn_w, $tn_h);

	// Do it in a temp image
    ImageCopyResized($tmp_img, $src_img, 0, 0, 0, 0, $tn_w, $tn_h, $org_w, $org_h);

	// Initialize destination image
    $dst_img = imagecreatetruecolor($tn_w,$tn_w);

	// Do it in a temp image
    ImageCopy($dst_img, $tmp_img, 0, 0, 0, 0, $tn_w, $tn_w);

	// Save it!
    $thumb = get_thumb_filename($jpegFN);
    ImageJPEG($dst_img, $tnDir .$thumb, $jpegQuality);

	return 0;
}

/**
 * generic:
 * build a valid "thumbname" from a given image file name
 * e.g.: myimage.png becomes myimage_th.png
 */
function get_thumb_filename($imgFN){
    $comp = explode('.', $imgFN);
    return $comp[0] ."_th." .$comp[1];
}
// ------------------------------------------------- end of mk_lib_images
?>
